﻿using System;
using System.Linq;
using System.Linq.Expressions;

using VirtualTournaments.DataAccess.SqlServer.DataMappers;

namespace VirtualTournaments.DataAccess.SqlServer.DataProxies
{
	internal sealed class MatchDataProxy : Business.Tournaments.Match, IDataProxy<SqlServer.Match>, Identifiable<SqlServer.Match>
	{
		internal MatchDataProxy(SqlServer.Match dataObject)
			: base(null, null, null)
		{
			InnerDataObject = dataObject;
			MapProperties();
		}

		#region Override properties

		internal bool TournamentHasBeenRead { get; set; }
		public override Business.Tournaments.Tournament Tournament
		{
			get
			{
				if (!TournamentHasBeenRead)
				{
					TournamentHasBeenRead = true;
					if (base.Tournament == null)
					{
						base.Tournament = MapTournament();
					}
				}
				return base.Tournament;
			}
		}

		internal bool LocalHasBeenRead { get; set; }
		public override Business.Tournaments.Team Local
		{
			get
			{
				if (!LocalHasBeenRead)
				{
					LocalHasBeenRead = true;
					if (base.Local == null)
					{
						base.Local = MapLocal();
					}
				}
				return base.Local;
			}
		}

		internal bool VisitorHasBeenRead { get; set; }
		public override Business.Tournaments.Team Visitor
		{
			get
			{
				if (!VisitorHasBeenRead)
				{
					VisitorHasBeenRead = true;
					if (base.Visitor == null)
					{
						base.Visitor = MapVisitor();
					}
				}
				return base.Visitor;
			}
		}

		#endregion

		#region Mapping methods

		private void MapProperties()
		{
			this.IsPlayed = InnerDataObject.IsPlayed;
			this.Result = new MatchResultDataProxy(this);
		}

		private Business.Tournaments.Tournament MapTournament()
		{
			return AllAgainstAllTournamentsDataMapper.Instance.DataObject2BusinessObject(InnerDataObject.JourneysMatch.First().Journey.Tournament);
		}

		private Business.Tournaments.Team MapLocal()
		{
			return TeamsDataMapper.Instance.DataObject2BusinessObject(InnerDataObject.LocalTeam);
		}

		private Business.Tournaments.Team MapVisitor()
		{
			return TeamsDataMapper.Instance.DataObject2BusinessObject(InnerDataObject.VisitorTeam);
		}

		#endregion

		#region IDataProxy<Match> Members

		public SqlServer.Match InnerDataObject { get; set; }

		#endregion

		#region Identifiable<Match> Members

		public Expression<Func<SqlServer.Match, bool>> GetUniqueWhereExpression()
		{
			return match => match.MatchId == InnerDataObject.MatchId;
		}

		#endregion
	}
}
